package org.common.utils.fasttest;

import sun.misc.Unsafe;
import java.lang.invoke.MethodHandles;
import java.lang.invoke.VarHandle;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author zhouzhibing
 * @date 2024/8/23
 */
public class TestField {


    private final static ConcurrentHashMap<Long , Boolean> LOCK = new ConcurrentHashMap<>();

    public static void test() throws Exception {
        String classPath = System.getProperty("java.class.path");
        System.out.println("classPath = " + classPath);
        Name n = new Name();
        n.name = "abd";

        Boolean lock1 = LOCK.putIfAbsent(10000000L , true);
        Boolean lock2 = LOCK.putIfAbsent(Long.valueOf(10000000) , true);
        System.out.println();

//        testUnsafe(n);
//        testField(n);
//        testInvoke(n);
//        testVarHandle(n);
    }

    private static void testVarHandle(Name n)  throws Exception {
        VarHandle name = MethodHandles.lookup().findVarHandle(Name.class, "name", String.class);
        Test.doHandler("VarHandle.field getValue" , 1000000 , 10 , (i) -> {
            Object o = name.get(n);
        });
    }

    private static void testInvoke(Name n) {
        Test.doHandler("Name.field getValue" , 1000000 , 10 , (i) -> {
            String name = n.name;
        });
    }

    private static void testField(Name n) throws Exception {
        Field nameField = Name.class.getDeclaredField("name");
        nameField.setAccessible(true);
        Map<Class , Map<String , Field>> fieldMap = new ConcurrentHashMap<>();
        Map<String, Field> map = fieldMap.computeIfAbsent(Name.class, (k) -> new ConcurrentHashMap<>());
        map.put("name" , nameField);
        Test.doHandler("testField getValue" , 1000000 , 10 , (i) -> {
            try {
                Field nameField1 = fieldMap.get(Name.class).get("name");
                Object o = nameField1.get(n);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }
        });
    }

    private static void testUnsafe(Name n) throws Exception {
        Unsafe u = getUnsafe();
        Field nameField = Name.class.getDeclaredField("name");
        long nameOffset = u.objectFieldOffset(nameField);
        Map<Class , Map<String , Long>> fieldMap = Map.of(Name.class , Map.of("name" , nameOffset));

        Map<Class , Map<String , Long>> fieldMap1 = new HashMap<>();
        Map<String, Long> map = fieldMap.computeIfAbsent(Name.class, (k) -> new HashMap<>());
        map.put("name" , nameOffset);

        Test.doHandler("testUnsafe getValue" , 1000000 , 10 , (i) -> {
            long offset = fieldMap.get(Name.class).get("name");
            Object object = u.getObject(n, offset);
        });

    }

    private static class Name {
        private String name;
    }

    private static Unsafe getUnsafe() {
        try {
            Field field = Unsafe.class.getDeclaredField("theUnsafe");
            field.setAccessible(true);
            return (Unsafe) field.get(null);
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }
}
